-
Notifications
You must be signed in to change notification settings - Fork 58
remove thin triangles from polygon boundaries (issue #2560) #2581
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This PR is working now. |
WARNING
UPDATE: This PR no longer fails this unit test. -Andrew 2025-6-22 |
c9d88bc
to
463dd9a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6 files reviewed, 2 comments
Edit PR Review Bot Settings | Greptile
…mely thin triangles in polygons created by ClipOperation are now deleted automatically.
463dd9a
to
8b0de95
Compare
Diff CoverageDiff: origin/develop...HEAD, staged and unstaged changes
Summary
tidy3d/components/geometry/base.py
|
Well, I would definitely not be removing a test assertion without understanding if it's OK. This sounds like something maybe @weiliangjin2021 should take a look at (but he might not be able to right now). |
Sorry, I shouldn't ask you to check that for me. It was late and I was lazy. weiliangjin2021 is (hopefully) not checking messages. He shouldn't be. I'll take another look at this test case today. (How did you know it was weiliangjin2021?) |
yea I agree with @momchil-flex we should be really careful about removing a test before understanding exactly whether this is intended behavior.
Wailing wrote most of the polyslab operations. Also, for future reference, you can check out the "blame" in GitHub to see who added which lines ![]() |
…hat I added to the function. Now I am much less worried that this PR breaks things that were working before.
UPDATE: DON'T REVIEW YET My code is working. But here are some new issues I just discovered: This PR is slow
Apparently, I am reinventing the wheelDaniil wrote a similar function named Both of us are trying to discard vertices in a polygon's boundary which are (almost) collinear with their neighbors. Perhaps I should try and consolidate our code?
I would like to consolidate both functions into a single function which accomplishes both goals and avoids for-loops. @dbochkov-flexcompute , do you mind if I do that? Or do you prefer I keep my code separate? |
corner finding feature was also developed by @weiliangjin2021, I only made small modifications 😃 . But I don't see a reason against generalizing |
Thanks Daniil! I'll proceed with that today. |
The code is in a broken state. |
@jewettaijfc I think this is getting into dangerous territory. I need to understand a bit better. We definitely dont want to take on such a big performance hit just to fix a very edge case plotting issue. I also want to see if there's something deeper going on that we need to fix in the intersection code. If so it might be better leaving this to Daniil or Weiliang to look at when they have time, since it is very complex. First let me test my understanding: The extra thin triangle in the plot is simply an artifact of the intersection of a polygon with a plane in some edge cases? or is the triangle "present" in the actual simulation? Is the numerical precision issue causing this fixable in the intersection code itself? If so it might be better than trying to do a pass through the polygon before plotting. We might have inadvertently opened up a 2nd "can of worms" issue here. Let's try to understand exactly what's going on and communicate with @dbochkov-flexcompute about the best solution before you expend too much effort trying to solve it. In the mean time, it might be worth trying to wrap up the other PR or start on the newly assigned ones. |
@jewettaijfc from a quick look at the current state, it looks like you end up not reusing corner finder after all but rather used some ideas to improve the performance of the new polygon cleaning function, is that the case? |
…eated vertices. The unit tests (that I added to this PR) are also working. I am using numpy magic to avoid all for-loops.
Yes. That's true. Perhaps I should not touch the code that's already working.
Yep! I did some more work to optimized the numpy code and reduced the plotting time from 1.57s down to 0.12s. (It's still slower than 0.07s, but keep in mind that that particular example has on the order of 10^5 vertices visible within the plot window.)
I think it's really much, much more likely to cause problems during plotting.
I won't say for sure. If the boundaries polygons fail to align exactly in 2D, then I suppose the same problem could happen for polyhedrons in 3D. (You could end up with really thin triangle-like "simplexes" in 3D.) The difference is that in 2D, if there is a thin triangle, it will be visible in the 2D plot regardless of how thin it is. But in 3D, I am guessing that having an extra thin wedge in the simulation would only matter if one of the FDTD grid points happened to fall within that thin volume. Since these triangles (or simplexes) are only about 1e-15 in width, that seems unlikely to happen.
I agree, but I couldn't think of a general way to do that. The problem is: once the original 3D objects have been rotated and then sliced by the view-plane to create 2D polygons, those 2D coordinates will never be perfectly aligned. So the intersections between them will always have a few spiky little triangles left over. The original issue #2560 describes a special case where the two objects ( But that's hard. The relevant code is here. The Incidentally, thanks for bearing with me during this power outage. I'm still at a cafe now. Hoping they fixed it by now. |
Shapely has a function to drop vertices below a resolution value: https://shapely.readthedocs.io/en/2.0.2/reference/shapely.set_precision.html I tried this line tidy3d/tidy3d/components/geometry/base.py Line 1258 in b6604ad
|
…nb intersecting rings example
…ing `cleanup_afterwards=False` by default. Polygon cleanup only happens when generating 2D plots of (intersecting) geometric shape objects (ie. using `ClipOperation.to_polygon_list()`)
weiliangjin2021 wrote:
Thanks! (That's awesome! I confess that before I started this PR, I asked both gemini and chatgpt how to delete long thin triangles from So I created a new PR which uses this approach (PR2596). If I had known about Weiliang's approach, I would not have bothered writing new code. But since we now have two solutions to this problem, here are the pros and cons of each approach:
Both PRs fix the glitch from issue-2560 and are ready for review. Choose whichever PR you prefer. Speed comparisonThe last cell of this jupyter file contains a benchmark example.
(All times reported are the best/fastest time after 10 attempts.) |
Incidentally, I resolved the problem with the failing unit test I reported earlier. |
Another consideration is that there might be some edge cases in the custom code, but already well handled in shapely that is based on GEOS (likely very robust). |
Good point Weiliang! I've been wondering about this too, and just found one of these examples! Here is an example where this PR fails. UPDATE: Actually both PRs fail on this example, depending on what rotation angle I use. But I figured out how to fix it:
As a result, I am closing this PR and suggesting that we follow the other PR that uses this approach. Thanks for all your help, @weiliangjin2021 ! It was incredibly helpful. |
This PR addresses issue #2560
This PR removes extremely thin triangles (sometimes called "empty triangles") from the boundaries of polygons that are displayed in plots. Such triangles are often generated when computing intersections of polygons which fail to line up exactly due to floating-point rounding errors. This was causing visual glitches mentioned in that issue, and shown below:
UPDATE: I just realized the code in this PR duplicates Daniil's CornerFinderSpec code. (See below.)
Before this PR
After this PR
Testing this PR
Unzip the file, open the notebook, and evaluate the cells.
test_pr2581.ipynb.zip
Other types of plots are unlikely to be affected by this PR. But I will include this code in my tests for PR2544 which are ongoing.
Greptile Summary
Fixes visual artifacts in geometry plotting by removing extremely thin triangles from polygon boundaries that occur due to floating-point precision issues during shape intersections.
cleanup_simple_polygon()
andcleanup_shapely_polygon()
functions intidy3d/components/geometry/base.py
to remove triangles thinner than 1e-12 unitsClipOperation.to_polygon_list()
for automatic handling of intersection artifactstest_layerrefinement.py
as exact collinearity checks are no longer neededversion.py
andpyproject.toml